#ifndef __WIZ_BASE_UTIL_SINGLETON_HPP__SHANHAOBO_19800429__
#define __WIZ_BASE_UTIL_SINGLETON_HPP__SHANHAOBO_19800429__

#include "../Type/WizBaseType.hpp"

namespace Wiz
{
    /// Singleton
    namespace Singleton
    {
        template <typename DerivedT, typename B = ::Wiz::Null::Type>
        class Type : public B
        {
            typedef DerivedT* PTR;
        private:
            static PTR& Data()
            {
                static PTR ms_Singleton = WIZ_NULLPTR;
                return ms_Singleton;
            }
        public:
            Type()
            {
                WIZ_ASSERT(::Wiz::NotValidPtr(this->Data()));
                this->Data() = ::Wiz::Cast::Static<PTR>(this);
            }
            ~Type()
            {
                WIZ_ASSERT(::Wiz::IsValidPtr(this->Data()));
                this->Data() = 0;
            }
        public:
            static DerivedT& SingletonRef()
            {
                WIZ_ASSERT(::Wiz::IsValidPtr(Data()));
                return *(Data());
            }
            static PTR SingletonPtr()
            {
                WIZ_ASSERT(::Wiz::IsValidPtr(Data()));
                return Data();
            }
        private:  // emphasize the following members are private
            Type(const Type&);
            const Type& operator=(const Type&);
        };
    } /// end of namespace Singleton
    
#define WIZ_SINGLETON_NAMESPACE(DerivedT)          \
    WIZ_INLINE DerivedT& SingletonRef()            \
    {                                       \
        return DerivedT::SingletonRef();           \
    }                                       \
    WIZ_INLINE DerivedT* SingletonPtr()            \
    {                                       \
        return DerivedT::SingletonPtr();           \
    }
} /// end of namespace Wiz

#endif /*__WIZ_BASE_UTIL_SINGLETON_HPP__SHANHAOBO_19800429__*/
